package cn.ljy.mes.service.impl;

import cn.ljy.authority.service.impl.IBaseService;
import cn.ljy.common.exception.model.MyConfirmException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.MyWebException;
import cn.ljy.mes.dao.mapper.MesCarTechnologyDetailMapper;
import cn.ljy.mes.dao.mapper.MesCarTechnologyMapper;
import cn.ljy.mes.dao.mapper.MesProductionOrderMapper;
import cn.ljy.mes.model.MesCarTechnology;
import cn.ljy.mes.model.MesCarTechnologyDetail;
import cn.ljy.mes.model.query.MesCarTechnologyDetailQuery;
import cn.ljy.mes.model.query.MesCarTechnologyQuery;
import cn.ljy.mes.model.query.MesProductionOrderQuery;
import cn.ljy.mes.service.MesCarTechnologyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
@Validated//表示开启sprint的校检框架，会自动扫描方法里的@Valid（@Valid注解一般写在接口即可）
@Slf4j
public class IMesCarTechnologyService extends IBaseService<MesCarTechnology, MesCarTechnologyQuery> implements MesCarTechnologyService {
    @Autowired
    private MesCarTechnologyMapper mapper;
    @Autowired
    private MesCarTechnologyDetailMapper carTechnologyDetailMapper;
    @Autowired
    private MesProductionOrderMapper productionOrderMapper;


    @Override
    protected void enrichEntityFields(MesCarTechnology carTechnology) {
        //获取工艺详情数量
        MesCarTechnologyDetailQuery carTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
        carTechnologyDetailQuery.setCarTechnology(carTechnology);
        carTechnology.setCarTechnologyDetailNumber(carTechnologyDetailMapper.count(carTechnologyDetailQuery));
    }

    @Override
    protected void afterGet(MesCarTechnology carTechnology) {
        if(carTechnology!=null){
            //获取工艺详情集合
            MesCarTechnologyDetailQuery carTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
            carTechnologyDetailQuery.setCarTechnology(carTechnology);
            carTechnology.setCarTechnologyDetails(carTechnologyDetailMapper.findAll(carTechnologyDetailQuery));
        }
    }

    @Override
    protected void beforeSaveOrUpdate(MesCarTechnology carTechnology) {
        //获取工艺详情集合
        List<MesCarTechnologyDetail> carTechnologyDetails = carTechnology.getCarTechnologyDetails();
        if(carTechnologyDetails!=null&&carTechnologyDetails.size()>0){
            for(int index=0;index<carTechnologyDetails.size();index++){
                //进行验证
                MesCarTechnologyDetail carTechnologyDetail=carTechnologyDetails.get(index);
                if(carTechnologyDetail.getMaterial()==null||carTechnologyDetail.getMaterial().getId()==null){
                    throw new MyWebException("验证失败：工艺详情中的物料不能为空，请选择物料后重新提交！");
                }
                if(carTechnologyDetail.getQuantity()!=null&&carTechnologyDetail.getQuantity()<=0){
                    throw new MyWebException("验证失败：工艺详情中的数量有误，请重新填写后提交！");
                }
                //检查工艺详情的排序是否正确(重要）
                if(carTechnologyDetail.getSort()!=index+1){
                    throw new MyWebException("验证失败：工艺详情的排序不正确，请检查重新提交！");
                }
                //如果是编辑，可以先赋值工艺到详情，方便后面批量保存。
                if(carTechnology.getId()!=null){
                    carTechnologyDetail.setCarTechnology(carTechnology);
                }
            }
        }
    }

    @Override
    protected void beforeSave(MesCarTechnology carTechnology) {
        if(carTechnology.getCarModelConfig().getId()==null){
            throw new MyWebException("验证失败：车型不能为空");
        }
        //检查编号是否重名
        MesCarTechnologyQuery carTechnologyQuery=new MesCarTechnologyQuery();
        carTechnologyQuery.setCode(carTechnology.getCode());
        if(mapper.count(carTechnologyQuery)>0){
            throw new MyWebException("验证失败：编码不能重名");
        }
        //启用状态默认是未启用，需要手动执行启用
        carTechnology.setEnabled(false);
    }

    @Override
    protected void beforeUpdate(MesCarTechnology carTechnology) {
        carTechnology.setEnabled(null);//启用状态必须在专门的函数中修改
        //检查该工艺是否已经用于实际生产，如果已经使用则不允许编辑和删除
        MesProductionOrderQuery productionOrderQuery=new MesProductionOrderQuery();
        productionOrderQuery.setCarTechnology(carTechnology);
        int productionOrderNumber=productionOrderMapper.count(productionOrderQuery);
        if(productionOrderNumber>0){
            throw new MyServiceException(String.format("该工艺已经用于%d辆汽车生产上，禁止变更！",productionOrderNumber));
        }
        //检查编号是否重名
        MesCarTechnologyQuery carTechnologyQuery=new MesCarTechnologyQuery();
        carTechnologyQuery.setCode(carTechnology.getCode());
        if(mapper.countByCodeAndNotId(carTechnology.getCode(),carTechnology.getId())>0){
            throw new MyWebException("验证失败：编码不能重名");
        }
        //检查是否启用，如果启用了则要验证，同一个车型下只能有一个工艺同时启用
        MesCarTechnology mesCarTechnologyOfOrignl=mapper.findById(carTechnology.getId());//获取完整记录
        if(mesCarTechnologyOfOrignl.getEnabled()){//如果工艺是启用状态
            //如果本次修改包含生产步骤,修改后的生产步骤不能为空。
            if(carTechnology.getCarTechnologyDetails()!=null&&carTechnology.getCarTechnologyDetails().size()==0){
                throw new MyServiceException("更新失败：启用的生产工艺必须包含生产步骤");
            }
        }
    }

    @Override
    protected void afterSave(MesCarTechnology carTechnology) {
        //先为详情赋值所属工艺对象，再保存
        List<MesCarTechnologyDetail> carTechnologyDetails = carTechnology.getCarTechnologyDetails();
        if(carTechnologyDetails!=null&&carTechnologyDetails.size()>0) {
            for(MesCarTechnologyDetail carTechnologyDetail:carTechnologyDetails){
                carTechnologyDetail.setCarTechnology(carTechnology);
            }
        }
        //保存工艺集合
        carTechnologyDetailMapper.saveAllIn(carTechnology.getCarTechnologyDetails());
    }

    @Override
    protected void afterUpdate(MesCarTechnology carTechnology) {
        //注意，因为后续增加了可以编辑局部属性，此时前端可能会没有传递工艺详情步骤过来，因此需要增加判断。但是不能加size的集合数量判断，因为允许步骤为空。
        if(carTechnology.getCarTechnologyDetails()!=null){
            //删除原来的工艺详情
            carTechnologyDetailMapper.deleteByMesCarTechnologyId(carTechnology.getId());
            //保存工艺集合
            carTechnologyDetailMapper.saveAllIn(carTechnology.getCarTechnologyDetails());
        }
    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        Map<String,String> errorMessageMap=new HashMap();
        for(Serializable id:ids){
            //获取工艺详情数量
            MesCarTechnology carTechnology=mapper.findById(id);
            if(carTechnology!=null){
                MesCarTechnologyDetailQuery mesCarTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
                mesCarTechnologyDetailQuery.setCarTechnology(new MesCarTechnology(id.toString()));
                int carTechnologyDetailNumber=carTechnologyDetailMapper.count(mesCarTechnologyDetailQuery);
                if(carTechnologyDetailNumber>0){
                    errorMessageMap.put(carTechnology.getName(),String.valueOf(carTechnologyDetailNumber));
                }
            }
        }
        //确定是否抛出错误信息
        if(errorMessageMap.size()>0){
            throw new MyConfirmException("%s已存在%s个工艺步骤",errorMessageMap);
        }
    }
    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        for(Serializable id:ids){
            //检查该工艺是否已经用于实际生产，如果已经使用则不允许编辑和删除
            MesProductionOrderQuery productionOrderQuery=new MesProductionOrderQuery();
            productionOrderQuery.setCarTechnology(new MesCarTechnology(String.valueOf(id)));
            int productionOrderNumber=productionOrderMapper.count(productionOrderQuery);
            if(productionOrderNumber>0){
                throw new MyServiceException(String.format("该工艺已经用于%d辆汽车生产上，禁止删除！",productionOrderNumber));
            }
            //删除工艺详情集合
            carTechnologyDetailMapper.deleteByMesCarTechnologyId(id.toString());
        }
    }

    @Override
    public void changeEnabled(String id, Boolean enabled) {
        //1.检查是否启用，如果启用了则要验证，同一个车型下只能有一个工艺同时启用
        MesCarTechnology carTechnology=mapper.findById(id);
        if(carTechnology==null){
            throw new MyServiceException("订单启用状态变更失败：订单号在系统中不存在");
        }
        //2.如果订单要改为启用状态
        if(!carTechnology.getEnabled()&&enabled){//如果原来不是启用状态，但是现在变为启用
            //2.1对启用状态进行判断，判断同车型配置下是否有已经启用的工艺。因为原来未启用，因此查到的启用状态不可能大于1
            MesCarTechnologyQuery carTechnologyQuery=new MesCarTechnologyQuery();
            carTechnologyQuery.setCarModelConfig(carTechnology.getCarModelConfig());
            carTechnologyQuery.setEnabled(true);
            if(mapper.count(carTechnologyQuery)>0){
                throw new MyServiceException(String.format("更新失败：车型配置（%s）已经有在使用的工艺，请先停止后再启用",
                        carTechnology.getCarModelConfig().getName()));
            }
            //2.2 检查生产步骤，启用状态下生产步骤不能为空。
            MesCarTechnologyDetailQuery carTechnologyDetailQuery=new MesCarTechnologyDetailQuery();
            carTechnologyDetailQuery.setCarTechnology(carTechnology);
            int carTechnologyDetailNumber=carTechnologyDetailMapper.count(carTechnologyDetailQuery);
            if(carTechnologyDetailNumber==0){
                throw new MyServiceException("更新失败：启用的生产工艺必须包含生产步骤");
            }
        }
        carTechnology.setEnabled(enabled);
        mapper.update(carTechnology);
    }
}
